#include "Acceptor.h"
#include "Network.h"
#include <iostream>
using namespace tmms::network;

Acceptor::Acceptor(EventLoop * loop,const InetAddress &addr)
:Event(loop),addr_(addr)
{

}


Acceptor::~Acceptor()
{
    Stop();
    if(socket_opt_)
    {
        delete socket_opt_;
        socket_opt_ = nullptr;
    }
}


void Acceptor::SetAcceptCallback(const AcceptCallback &cb)
{
    accept_cb_  = cb;
}

void Acceptor::SetAcceptCallback(const AcceptCallback &&cb)//成功接受连接之后的回调函数
{
    accept_cb_ = std::move(cb);
}

void Acceptor::Open() //创立新的fd，一个Acceeptor只有一个fd
{
    if(fd_>0) //之前已经创建了
    {
        ::close(fd_);
        fd_=-1;
    }

    if(addr_.IsIpV6()){
        fd_ = SocketOpt::CreateNonblockingTcpSocket(AF_INET6);
    }else{
        fd_ = SocketOpt::CreateNonblockingTcpSocket(AF_INET);
    }

    if(fd_<0){
        NEWORK_ERROR<<"socket failed error "<<errno;
        exit(-1);
    }
    if(socket_opt_)
    {
        delete socket_opt_;
        socket_opt_ = nullptr;
    }
    
    loop_->AddEvent(std::dynamic_pointer_cast<Acceptor>(shared_from_this())); //就这个有问题
    //loop_->AddEvent(shared_from_this()); 
   
    socket_opt_  = new SocketOpt(fd_);
    socket_opt_->SetReuseAddr(true);
    socket_opt_->SetReusePort(true);
    socket_opt_->BindAddress(addr_);
    socket_opt_->Listen(); //开启监听  
}

void Acceptor::Start()
{
    loop_->RunInLoop([this](){ //保证他们在同一个事件循环下面，往eventloop中加入一个任务队列
        Open();
    });
}

void Acceptor::Stop()
{
    loop_->DelEvent(std::dynamic_pointer_cast<Acceptor>(shared_from_this()));
}

void Acceptor::OnRead() 
/*​​事件触发逻辑​​：
当客户端发起连接时，内核会通知监听套接字的​​读事件就绪​​（EPOLLIN），此时 Acceptor 调用 accept() 接收新连接。
void Acceptor::OnRead() override {
    int conn_fd = accept(listen_fd_, ...); // 接收新连接
    accept_cb_(conn_fd, client_addr);      // 触发回调（如创建 Connection 对象）
}*/
{
    if(!socket_opt_)
    {
        return ;
    }
    while(true) //等待接入新连接，
    {
        InetAddress addr;
        auto sock = socket_opt_->Accept(&addr);//接受新的连接，必须先监听Start(),才可以Accept，会阻塞
        std::cout<<"wokankan ne "<<std::endl;
        if(sock>=0)
        {
            std::cout<<"wokankan a "<<std::endl;
            if(accept_cb_)
            {
                accept_cb_(sock,addr); //触发回调，连接成功的回调，创建connecttion

            }
        }
        else
        {
            if(errno!=EINTR&&errno!=EAGAIN)
            {
                NEWORK_ERROR << "acceptor error :"<<errno;
                OnClose();
            }
            break;
        }
    }
}

void Acceptor::OnError(const std::string &msg) 
{
    NEWORK_ERROR << "acceptor error :"<<msg;
    OnClose();
}
void Acceptor::OnClose()
{
    Stop();
    Open();
}
